/**
 * 文件名:BaseManager.java<br>
 * 版本: <br>
 * 描述: <br>
 * 版权所有: <br>
 * //////////////////////////////////////////////////////// <br>
 * 创建者: robo<br>
 * 创建日期: 2010-11-24 <br>
 * 修改者: <br>
 * 修改日期: <br>
 * 修改说明: <br>
 */
package com.sunwayhorizo.health.business.base;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.log.Log;

import com.sunwayhorizo.health.business.base.query.BaseQueryLocal;
import com.sunwayhorizo.health.business.dto.DictionaryDTO;
import com.sunwayhorizo.health.business.dto.PageDTO;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.ets.factory.DictionaryFactory;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.CD;
import com.sunwayhorizo.health.hl7.datatypes.CS;
import com.sunwayhorizo.health.hl7.factories.ActFactory;
import com.sunwayhorizo.health.hl7.factories.DataTypeFactory;
import com.sunwayhorizo.health.hl7.factories.EntityFactory;
import com.sunwayhorizo.health.hl7.factories.RoleFactory;
import com.sunwayhorizo.health.hl7.rim.Act;
import com.sunwayhorizo.health.hl7.rim.ActParticipation;
import com.sunwayhorizo.health.hl7.rim.ActRelationship;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.Hl7Entity;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.rim.Rolelink;
import com.sunwayhorizo.health.hl7.vocabulary.ActMood;
import com.sunwayhorizo.health.hl7.vocabulary.ActRelationshipType;
import com.sunwayhorizo.health.hl7.vocabulary.DataContainer;
import com.sunwayhorizo.health.hl7.vocabulary.Direction;
import com.sunwayhorizo.health.hl7.vocabulary.Participation;

public class BaseManager implements IBaseManager
{

    @PersistenceContext(unitName = "sunwayhealth")
    public EntityManager em;

    @Logger
    public Log log;

    /**
     * 组织唯一标示，目前代表大庆油田总院
     */
    public String root = "192.168.0.1";

    /**
     * 前台返回值dto
     */
    public ResultsDTO dto = new ResultsDTO();

    /**
     * 术语dto
     */
    public DictionaryDTO dictionaryDto = new DictionaryDTO();

    /**
     * 批量增加，修改增长数，可以设置
     */
    public final static int batchSize = 1000;

    public BaseQueryLocal baseQuery = (BaseQueryLocal) Component.getInstance("BaseQuery");

    private List<DataContainer> containers = new ArrayList<DataContainer>();

    private Map<Participation, String> participations = new HashMap<Participation, String>();


    public DataTypeFactory getDataTypeFactory()
    {
        return DataTypeFactory.getInstance();
    }


    public EntityFactory getEntityFactory()
    {
        return EntityFactory.getInstance();
    }


    public ActFactory getActFactory()
    {
        return ActFactory.getInstance();
    }


    public RoleFactory getRoleFactory()
    {
        return RoleFactory.getInstance();
    }


    public DictionaryFactory getDictionaryFactory()
    {
        return DictionaryFactory.getInstance();
    }


    public String getEXTEN_CODE()
    {
        return em.createNativeQuery("select EXTEN_CODE.NEXTVAL from dual").getResultList().get(0).toString();
    }


    public String getSEQ_CLINICNO()
    {
        return em.createNativeQuery("select SEQ_CLINICNO.NEXTVAL from dual").getResultList().get(0).toString();
    }

    
    public String getSEQ_PATIENTID()
    {
        return  em.createNativeQuery("select SEQ_PATIENTID.NEXTVAL from dual").getResultList().get(0).toString();
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public <T> T find(Class<T> entityClass, Object primaryKey)
    {
        T obj = em.find(entityClass, primaryKey);
        return obj;
    }


    /**
     * 保存
     */
    public void save(Object entity)
    {
        em.persist(entity);
        em.flush();
        em.clear();
    }


    /**
     * 修改
     */
    public void update(Object entity)
    {
        em.merge(entity);
        em.flush();
        em.clear();
    }


    /**
     * 删除
     */
    public void delete(Class<?> entityClass, Object primaryKey)
    {
        em.remove(em.getReference(entityClass, primaryKey));
    }


    /**
     * 删除
     */
    public void delete(Object entity)
    {
        em.remove(em.merge(entity));
    }

    /**
     * 删除动作相关的角色，实体信息
     * @param act
     * @param participationType
     * @throws Hl7Exception
     */
    public int delete(Act act,CS participationType) throws Hl7Exception
    {
        int i = 0;
        if(act != null)
        {
            Role role = act.getRoleByAct(participationType);
            if(role != null)
             {
                Hl7Entity enty = role.getPlayerEntity();
                em.remove(enty);
                log.info("删除实体基本信息成功");
                em.remove(role);
                log.info("删除角色基本信息成功");
             }
            em.remove(act);
            i = 1;
            log.info("删除动作信息成功");
        }
        return i;
    }
    
    /**
     * 批量删除动作相关信息
     * @param actList 动作集合信息
     * @param participationType 动作关联的角色typeCode
     * @return 0：删除失败 1：删除成功
     * @throws Hl7Exception
     */
    public int batchDelete(List<? extends Act> actList,CS participationType) throws Hl7Exception
    {
        int i=0;
        if(ListUtil.isEmpty(actList)) return i;
        for(Act act : actList)
        {
            i = delete(act,participationType);
        }
        em.flush();
//        em.clear();
        return i;
    }

    /**
     * 得到返回的ResultsDTO 前台返回值公共方法
     * 
     * @param resultDesc
     *            成功与否的描述信息
     * @param resultFlag
     *            成功与否的标志信息(true,false)
     * @param returnObj
     *            返回的数据List,Object
     * @return ResultsDTO
     * @throws Hl7Exception
     */
    public ResultsDTO getResultsDTO(String resultDesc, boolean resultFlag, Object returnObj) throws Hl7Exception
    {
        ResultsDTO dto = new ResultsDTO();
        dto.setResultFlag(resultFlag);
        dto.setResultDesc(resultDesc);
        dto.setObject(returnObj);
        return dto;
    }


    /**
     * 得到返回的ResultsDTO 前台返回值公共方法
     * 
     * @param desc
     *            成功与否的描述信息
     * @param flag
     *            成功与否的标志信息(true,false)
     * @param obj
     *            返回的数据List,Object
     * @param pageDTO
     *            返回的分页信息
     * @return ResultsDTO
     * @throws Hl7Exception
     */
    public ResultsDTO getResultsDTO(String desc, boolean flag, Object obj, PageDTO pageDTO) throws Hl7Exception
    {

        ResultsDTO dto = getResultsDTO(desc, flag, obj);
        dto.setBeginIndex(dto.getPageSize() * (pageDTO.getPageNo() - 1));
        dto.setTotalRecords(pageDTO.getTotalRecord());
        dto.setPageSize(pageDTO.getPageSize());
        dto.setToPage(pageDTO.getPageNo());

        return dto;
    }


    /**
     * 注册业务保存公共方法。外部创建的Role可以跟Act建立关系
     * 
     * @param code
     *            act code值
     * @param typeCode
     *            RimCoreActPrtcptns typeCode值
     * @param id
     *            序列
     * @param role
     *            需要跟act建立关系的Role
     * @return
     * @throws Hl7Exception
     */
    public ControlAct newControlAct(CD code, CS typeCode, String id, Role role) throws Hl7Exception
    {
        // 创建ControlAct

        ControlAct controlAct = getActFactory().newControlActEvent(null, null);

        // 创建ACT

        Act registrationAct = getActFactory().newRegistryAct(ActMood.EVN, code, null);

        // 创建ControlAct与ACT的关系
        controlAct.addOBActRelationship(ActRelationshipType.SUBJ, registrationAct);

        registrationAct.addParticipation(typeCode, role);
        
        return controlAct;
    }


    /**
     * 业务中多个角色参与到一个动作用此方法进行对ControlAct的保存
     * 
     * @param act
     *            业务中需要建立关系source动作
     * @return ControlAct
     * @throws Hl7Exception
     */
    public ControlAct newControlAct(Act act) throws Hl7Exception
    {
        ControlAct controlAct = getActFactory().newControlActEvent(null, null);
        controlAct.addOBActRelationship(ActRelationshipType.SUBJ, act);

        for (DataContainer con : containers)
        {
            if (con.getType().equals(ActParticipation.class.getSimpleName()))
            {
                act.addParticipation(con.getActParticipation(), con.getRole());
            }
            else if (con.getType().equals(ActRelationship.class.getSimpleName()))
            {
                switch (con.getDirection())
                {
                    case SOURCE:
                        act.addOBActRelationship(con.getActRelationship(), con.getAct());
                        break;

                    case TARGET:
                        act.addIBActRelationship(con.getActRelationship(), con.getAct());
                        break;
                }
            }
            else if (con.getType().equals(Rolelink.class.getSimpleName()))
            {
                Role sourceRole = con.getSource();
                Role targetRole = con.getTarget();
                Rolelink rolelink = con.getRolelink();

                sourceRole.addSourceRole(rolelink);
                targetRole.addTargetRole(rolelink);
                rolelink.setSourceRole(sourceRole);
                rolelink.setTargetRole(targetRole);

                if (!controlAct.getControlActRolesList().contains(sourceRole))
                {
                    controlAct.addControlActRole(sourceRole);
                }
                if (!controlAct.getControlActRolesList().contains(targetRole))
                {
                    controlAct.addControlActRole(targetRole);
                }
                controlAct.addControlActRoleLink(rolelink);
                if (!controlAct.getControlActEntitiesList().contains(sourceRole.getPlayerEntity()))
                {
                    controlAct.addEntity(sourceRole.getPlayerEntity());
                }
                if (!controlAct.getControlActEntitiesList().contains(sourceRole.getScoperEntity()))
                {
                    controlAct.addEntity(sourceRole.getScoperEntity());
                }
                if (!controlAct.getControlActEntitiesList().contains(targetRole.getPlayerEntity()))
                {
                    controlAct.addEntity(targetRole.getPlayerEntity());
                }
                if (!controlAct.getControlActEntitiesList().contains(targetRole.getPlayerEntity()))
                {
                    controlAct.addEntity(targetRole.getPlayerEntity());
                }

            }
        }
        containers.clear();
        return controlAct;
    }





    /**
     * 批量保存
     * 
     * @param os
     *            批量保存集合
     */
    @SuppressWarnings("rawtypes")
    public void batchSave(final Collection os) throws Hl7Exception
    {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("sunwayhealth");
        EntityManager manager = factory.createEntityManager();
        Iterator it = os.iterator();
        int i = 0;
        while (it.hasNext())
        {
            i++;
            manager.persist(it.next());
            if (i % batchSize == 0)
            {
                em.flush();
                em.clear();
            }
        }
    }


    /**
     * 批量修改
     * 
     * @param os
     *            批量修改的集合
     * @return boolean
     */
    @SuppressWarnings("rawtypes")
    public boolean batchUpdate(final Collection os) throws Hl7Exception
    {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("sunwayhealth");
        EntityManager manager = factory.createEntityManager();
        Iterator it = os.iterator();
        int i = 0;
        while (it.hasNext())
        {
            i++;
            manager.merge(it.next());
            if (i % batchSize == 0)
            {
                em.flush();
                em.clear();
            }
        }
        return true;
    }
    
    public List<DataContainer> getContainers()
    {
        return containers;
    }


    protected Map<Participation, String> getParticipations()
    {
        return participations;
    }


    protected void setParticipations(Map<Participation, String> participations)
    {
        this.participations = participations;
    }


    public void addParticipation(Role role, ActParticipation part)
    {
        containers.add(new DataContainer(role, part));
    }


    public void addRelationship(Act act, ActRelationship relation, Direction dir)
    {
        containers.add(new DataContainer(act, relation, dir));
    }


    public void addRoleLink(Role source, Role target, Rolelink rolelink)
    {
        containers.add(new DataContainer(source, target, rolelink));
    }

}
